package com.aistar.service.job.impl;

import com.aistar.mapper.*;
import com.aistar.model.entity.Delivery;
import com.aistar.model.entity.EmployerBlacklist;
import com.aistar.model.entity.Resume;
import com.aistar.service.job.ICompanyService;
import com.aistar.service.job.IDeliveryService;
import com.aistar.service.job.IRecruitmentService;
import com.aistar.util.DateUtil;
import org.apache.jasper.compiler.ELInterpreter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.crypto.Data;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class DeliveryServiceImpl implements IDeliveryService {
    @Autowired
    private DeliveryMapper deliveryMapper;
    @Autowired
    private EmployerBlacklistMapper employerBlacklistMapper;
    @Autowired
    private ResumeMapper resumeMapper;
    @Autowired
    private RecruitmentMapper recruitmentMapper;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private EmployerMapper employerMapper;
    @Autowired
    private EmployeeBlacklistMapper employeeBlacklistMapper;
    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public int addDelivery(Integer recruitmentId, Integer resumeId) {
        Delivery delivery = new Delivery();
        delivery.setRecruitmentId(recruitmentId);
        delivery.setResumeId(resumeId);
        delivery.setDeliveryTime(new Date());
        delivery.setStatus("未处理");
        Integer employeeId=resumeMapper.findById(resumeId).getEmployeeId();
        System.out.println(employeeId);
        List<Resume> resumeList = new ArrayList<>();
        resumeList=resumeMapper.findByEmployeeId(employeeId);
        List<Long> count = new ArrayList<>();
        for (Resume resume : resumeList) {
            int XX = resume.getId();
            List<Delivery> delivery1=deliveryMapper.findByRidAndRsId(recruitmentId, XX);
            for (Delivery delivery2 : delivery1) {
                count.add(delivery2.getDeliveryTime().getTime());
            }
        }
        Long time=0L;
        if(null!=count && count.size()>0){
            if(count.size()>1){
                time=Collections.max(count);
            }else{
                time=count.get(0);
            }
        }
        Date date=new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String fmDate = sdf.format(date);
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(date);
        Integer month=calendar.get(Calendar.MONTH)+1;
        Date date1 = new Date();
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Integer month1=calendar1.get(Calendar.MONTH)+1;
        Integer companyId=recruitmentMapper.findById(recruitmentId).getCompanyId();
        Integer erid=employerMapper.findByCompanyId(companyId);
        List<Integer> employerBlacklistList= recruitmentMapper.findByEmployer(erid);
        List<Integer> employeeBlacklistMapperByRecruitmentId=employeeBlacklistMapper.findByRecruitmentId(employeeId);
        List<Delivery> delivery2=deliveryMapper.findByRidAndRsId(recruitmentId,resumeId);
        if(delivery2!=null || delivery2.size()>0){
            if(month1-month<3){
                return 0;
            }else if(employerBlacklistList.contains(employeeId)){
                return -1;
            }else if(employeeBlacklistMapperByRecruitmentId.contains(companyId)){
                return 2;
            }else{
                return deliveryMapper.save(delivery);
            }
        }
        return 0;
    }

    @Override
    public List<Delivery> getDeliveryList(Integer employeeId, Integer recruitmentId) {
        // 根据求职者id和职位id获取所有的投递记录
        // 首先根据求职者id获取所有的简历id
        List<Integer> resumeIdList = new ArrayList<>();
        resumeIdList = resumeMapper.findResumeIdByEmployeeId(employeeId);
        // 判断该用户是否有简历id
        if(resumeIdList==null || resumeIdList.size()==0)
            return null;
        List<Delivery> deliveryList = new ArrayList<>();
        // 遍历简历id
        for (Integer resumeId : resumeIdList) {
            // 根据简历id和职位id获取所有的简历投递记录
            List<Delivery> deliveries = deliveryMapper.findByRidAndRsId(recruitmentId,resumeId);
            if(null!=deliveries && deliveries.size()>0){
                // 遍历集合,把所有数据都添加到deliveryList中
                for (Delivery delivery : deliveries) {
                    deliveryList.add(delivery);
                }
            }
        }

        return deliveryList;
    }

    @Override
    public boolean judgeDelivery(Integer recruitmentId, Integer employeeId) {
        // 判断是否可以进行投递
        // 首先读取redis中的数据,查看是否存在数据
        // redis中存储的key:delivery_求职者id_职位id;value:投递时间
        ValueOperations vop = redisTemplate.opsForValue();
        String key = "delivery_"+employeeId+"_"+recruitmentId;
        // 定义三个月的毫秒数
        Long threeTime = 3L * 30 * 24 * 60 * 60 * 1000;
        // 获取今天的毫秒数
        Long nowTime = new Date().getTime();
        // 根据求职者id和职位id去redis中查询数据 - 判断是否有该key所对应的值
        if(redisTemplate.hasKey(key)){
            // 如果有则查询redis中的数据
            // 这里有一个设定,只要redis里面有数据,那一定是最新一次投递的记录
            // 查询这个投递记录的时间看距离今天是否有三个月
            String delivery = (String) vop.get(key);
            // 获取投递时的毫秒数
            Long deliveryTime = DateUtil.parse(delivery,"yyyy-MM-dd HH:mm:ss").getTime();
            if(nowTime-deliveryTime-threeTime>0){
                // 说明最近一次投递在三个月之前
                return true;
            }else{
                return false;
            }
        }else {
            // 如果在redis中没有查询到记录,就要去mysql中查询记录
            // 首先查询出该求职者在该职位所有的投递记录
            List<Delivery> deliveryList = getDeliveryList(employeeId,recruitmentId);
            if(deliveryList!=null && deliveryList.size()>0){
                // 进行排序,获取出最新的一份投递记录[按时间倒序排序]
                deliveryList.sort((o1,o2)->{
                    if(o1.getDeliveryTime().getTime()>o2.getDeliveryTime().getTime())
                        return -1;
                    else if(o1.getDeliveryTime().getTime()<o2.getDeliveryTime().getTime())
                        return 1;
                    return 0;
                });
                // 获取最新的一份投递记录
                Delivery newestDelivery = deliveryList.get(0);
                // 获取投递时的毫秒数
                Long deliveryTime = newestDelivery.getDeliveryTime().getTime();
                // 判断这份投递记录的时间是否大于三个月
                if(nowTime-deliveryTime-threeTime>0){
                    // 说明最近一次投递在三个月之前
                    return true;
                }else{
                    // 说明最后一次投递在三个月之内
                    // 还需要往redis里插入查询到的数据
                    // redis中存储的key:delivery_求职者id_职位id;value:投递时间
                    String value = DateUtil.format(newestDelivery.getDeliveryTime(),"yyyy-MM-dd HH:mm:ss");
                    vop.set(key,value);
                    // 设置过期时间
                    redisTemplate.expire(key,7, TimeUnit.DAYS);
                    return false;
                }
            }
            // 走到这里表示根本没有投递记录
            return true;
        }
    }

    @Override
    public void saveToRedis(Integer resumeId, Integer recruitmentId, Integer employeeId) {
        // 根据职位id获取公司id
        Integer companyId = recruitmentMapper.findById(recruitmentId).getCompanyId();
        // 根据公司id获取招聘者id
        Integer employerId = employerMapper.findByCompanyId(companyId);
        // 获取求职者名称
        String employeeName = employeeMapper.findNameById(employeeId);

        // 把临时数据[用于插表的数据]存储到redis中 - 需要存储两种数据
        // 第一种数据
        // key1:dev_求职者id_职位id;value:求职者id,职位id,简历id,投递时间[set集合]
        HashOperations hop = redisTemplate.opsForHash();
        String key = employeeId+"_"+recruitmentId;
        // 创建redis的value -> Map的形式
        Map<String,String> data1 = new HashMap<>();
        data1.put("employeeId",employeeId.toString());
        data1.put("recruitmentId",recruitmentId.toString());
        data1.put("resumeId",resumeId.toString());
        String deliveryTime = DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
        data1.put("deliveryTime",deliveryTime);
        hop.putAll("dev1_"+key,data1);
        // 设置过期时间为五分钟
        redisTemplate.expire(key,5,TimeUnit.MINUTES);


        // 第二种数据
        //key:dev2_求职者id_职位id;value:招聘者id,求职者名称
        // 创建redis的value -> Map的形式
        Map<String,String> data2 = new HashMap<>();
        data2.put("employerId",employerId.toString());
        data2.put("employeeName",employeeName);
        hop.putAll("dev2_"+key,data2);
        redisTemplate.expire(key,5,TimeUnit.MINUTES);


        // 发送消息
        redisTemplate.convertAndSend("deliver",key);

    }

    @Override
    public boolean judgeBlacklist(Integer recruitmentId, Integer employeeId) {
        // 首先判断该用户是否被屏蔽
        // 根据职位id获取公司id 根据公司id获取招聘者id 根据招聘者id获取所有的被屏蔽的求职者id
        Integer companyId = recruitmentMapper.findById(recruitmentId).getCompanyId();
        // 首先到redis中进行查询
        // key:erb_公司id value:职位id[set集合]
        SetOperations sop = redisTemplate.opsForSet();
        String key = "erb_" + companyId;
        // 判断redis中是否有数据
        if(sop.isMember(key,employeeId.toString())){
            // 如果有数据则表示被屏蔽了,直接返回true
            return true;
        }
        // redis里没有数据则要去mysql中查询
        // 首先根据公司id获取招聘者id
        Integer employerId = employerMapper.findCompanyIdById(companyId);
        // 根据招聘者id获取被屏蔽的求职者id
        List<Integer> employeeList = employerBlacklistMapper.findEmployeeIdByEmployerId(employerId);
        // 判断屏蔽列表里有没有该求职者id
        if(employeeList.contains(employeeId)){
            // 如果有则表示被屏蔽了,往redis里插入数据,同时返回true
            String value = employeeId.toString();
            sop.add(key,value);
            redisTemplate.expire(key,7, TimeUnit.DAYS);
            return true;
        }
        return false;
    }

    @Override
    public void saveToMysql(Integer resumeId, Integer recruitmentId, Date deliveryTime) {
        // 创建实体类存储数据
        Delivery delivery = new Delivery();
        delivery.setStatus("未处理");
        delivery.setResumeId(resumeId);
        delivery.setRecruitmentId(recruitmentId);
        delivery.setDeliveryTime(deliveryTime);
        // 调用mapper
        deliveryMapper.save(delivery);
    }
}
